package cn.fintecher.pangolin.service.dataimp.task;

import cn.fintecher.pangolin.common.enums.ImportDataExcelStatus;
import cn.fintecher.pangolin.common.enums.MessageType;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.entity.elastic.DistributeImportRecord;
import cn.fintecher.pangolin.entity.elastic.DistributeModel;
import cn.fintecher.pangolin.service.dataimp.elastic.DistributeImportRecordElastic;
import cn.fintecher.pangolin.service.dataimp.elastic.DistributeModelElastic;
import cn.fintecher.pangolin.service.dataimp.model.ImportDistributeModel;
import cn.fintecher.pangolin.service.dataimp.service.BaseService;
import cn.fintecher.pangolin.common.utils.RepositoryUtil;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 13:43 2019/10/17
 */

@Service("importDistributeTask")
public class ImportDistributeTask {
    private static final Logger log = LoggerFactory.getLogger(ImportDistributeTask.class);

    @Autowired
    private BaseService baseService;

    @Autowired
    private DistributeModelElastic distributeModelElastic;

    @Autowired
    private DistributeImportRecordElastic distributeImportRecordElastic;

    @Autowired
    private ImportDistributeFuture importDistributeFuture;

    @Async
    @Transactional
    public void processDistribute(InputStream inputStream, DistributeImportRecord record, String batchNumber, UserModel userModel) throws IOException {
        //错误集合
        List<String> errors = new ArrayList<>();
        //分案导入模型集合
        List<DistributeModel> models = new ArrayList<>();
        try {
            XSSFWorkbook xssfWorkbook = new XSSFWorkbook(inputStream);
            XSSFSheet sheet = xssfWorkbook.getSheetAt(0);
            List<CompletableFuture<ImportDistributeModel>> list = new ArrayList<>();
            List<ImportDistributeModel> importDistributeModels = new ArrayList<>();
            for (int i = 1; i < sheet.getLastRowNum() + 1; i++) {
                Row row = sheet.getRow(i);
                CompletableFuture<ImportDistributeModel> future = importDistributeFuture.generate(row, batchNumber);
                list.add(future);
            }
            for (CompletableFuture<ImportDistributeModel> future : list) {
                importDistributeModels.add(future.get());
            }
            importDistributeModels.forEach(e -> {
                errors.addAll(e.getErrors());
                if (Objects.nonNull(e.getDistributeModel())) {
                    models.add(e.getDistributeModel());
                }
            });
            if (models.isEmpty()) {
                record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
                String fileId = baseService.generateTxt(Collections.singletonList("模板中没有数据"), Long.toString(new Date().getTime()));
                record.setFileId(fileId);
            } else {
                if (!errors.isEmpty()) {
                    record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
                    String fileId = baseService.generateTxt(errors, batchNumber);
                    record.setFileId(fileId);
                } else {
                    //案件编号重复检查
                    List<String> errors1 = new ArrayList<>();
                    Map<String, List<DistributeModel>> map = models.stream().collect(Collectors.groupingBy(DistributeModel::getCaseNumber));
                    for (Map.Entry<String, List<DistributeModel>> entry : map.entrySet()) {
                        List<DistributeModel> modelList = entry.getValue();
                        if (modelList.size() > 1) {
                            errors1.add("导入的excel模板中存在【案件编号】为【" + entry.getKey() + "】的重复数据");
                        }
                    }
                    if (errors1.isEmpty()) {
                        RepositoryUtil.saveData(distributeModelElastic, models);
                        record.setTotalNumber(sheet.getLastRowNum());
                        record.setStatus(ImportDataExcelStatus.IMPORT_SUCCESSFULLY);
                    } else {
                        record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
                        String fileId = baseService.generateTxt(errors1, batchNumber);
                        record.setFileId(fileId);
                    }
                }
            }
            distributeImportRecordElastic.save(record);
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            record.setStatus(ImportDataExcelStatus.IMPORT_FAILED);
            String fileId = baseService.generateTxt(Collections.singletonList("导入模板有误"), Long.toString(new Date().getTime()));
            record.setFileId(fileId);
            distributeImportRecordElastic.save(record);
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            baseService.sendMsg(MessageType.DISTRIBUTE, userModel);
        }
    }
}
